<template>
  <div class="cesiumContainer" ref="cesiumContainer"></div>
</template>

<script setup>
import * as Cesium from "cesium";
import { onMounted, ref, reactive, getCurrentInstance } from "vue";
import GUI from "lil-gui";

const cesiumContainer = ref(null);
let model = reactive({});
let scene = reactive({});
let viewer = reactive({});
let polylines = reactive({});
const operation = {
  value: "",
  selectOptions: {
    带边框的线: "widePolyline",
    基本线: "basePloyline",
    发光线: "coloredPolyline",
    自动封闭的环线: "loopPolyline",
    恒向线: "rhumbLine",
    渐隐线段: "fadingPolyline",
    带箭头的线段: "localPolyline",
  },
};
let currentInstance = getCurrentInstance();
let gui = new GUI();
gui
  .add(operation, "value", operation.selectOptions)
  .name("加载线段")
  .onChange((e) => {
    console.log("广告牌", currentInstance);
    scene.primitives.removeAll();
    polylines[e]();
  });

// 相当于密钥，申请使用下边链接中的数据时需要用到
Cesium.Ion.defaultAccessToken =
  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIyOTQ0YTExZS02N2Y4LTQ2OTMtOWQ4NS1mNzE3ZWMwYTNmNmEiLCJpZCI6NDM1OCwiaWF0IjoxNjI4MTQzMjE1fQ.csECCT352LHVhak2sJlWYXw_gr7U-AqdQ9UMvtfOeg8";
class Polylines {
  scene=null;
  constructor(scene) {
     this.scene = scene;
  } 
  get(){
    return this.scene;
  }
  //带边框的线
  /**
 * 创建并添加一个宽广的多段线到场景中。
 * 该函数不接受参数且无返回值。
 */
widePolyline() {
  // 创建一个PolylineCollection实例并将其添加到场景的primitives集合中
  let polyLines = this.scene.primitives.add(new Cesium.PolylineCollection());

  // 向polyLines集合中添加一个新的多段线对象
  polyLines.add({
    // 通过Cartesian3坐标数组生成一个弧形路径
    positions: Cesium.PolylinePipeline.generateCartesianArc({
      positions: Cesium.Cartesian3.fromDegreesArray([
        70, 40, 80, 40, 90, 40, 100, 40, 110, 40, 120, 40, 130, 40,
      ]),
    }),
    // 设置多段线的材质为描边样式，且指定描边宽度
    material: Cesium.Material.fromType(
      Cesium.Material.PolylineOutlineType, 
      {
        outlineWidth: 2,
      }
    ),
    width: 10, // 设置多段线的主宽度
  });
}
  //基本线
  basePloyline() {
    let polylines = this.scene.primitives.add(new Cesium.PolylineCollection());
    polylines.add({
      positions: Cesium.PolylinePipeline.generateCartesianArc({
        positions: Cesium.Cartesian3.fromDegreesArray([
          70, 39, 80, 39, 90, 39, 100, 39, 110, 39, 120, 39, 130, 39,
        ]),
      }),
      material: Cesium.Material.fromType("Color", {
        color: Cesium.Color.YELLOW,
      }),
    });
  }
  //发光线
  coloredPolyline() {
    let polylines = this.scene.primitives.add(new Cesium.PolylineCollection());
    polylines.add({
      positions: Cesium.PolylinePipeline.generateCartesianArc({
        positions: Cesium.Cartesian3.fromDegreesArray([70, 42, 130, 42]),
      }),
      material: Cesium.Material.fromType(Cesium.Material.PolylineGlowType, {
        glowPower: 1, //发光强度
        taperPower: 0.5, //控制线宽的衰减
        color: new Cesium.Color(1, 5, 0, 1),
      }),
      width: 10,
    });
  }
  //最后一条线进行链接开始位置封闭
  loopPolyline() {
    let polylines = this.scene.primitives.add(new Cesium.PolylineCollection());
    polylines.add({
      positions: Cesium.PolylinePipeline.generateCartesianArc({
        positions: Cesium.Cartesian3.fromDegreesArray([
          100, 37, 90, 37, 90, 36, 100, 36,
        ]),
      }),
      width: 5,
      loop: true,
    });
  }

  //两个任一点就可以画出一条曲线而不是折线
  rhumbLine() {
    let polylines = this.scene.primitives.add(new Cesium.PolylineCollection());
    polylines.add({
      positions: Cesium.PolylinePipeline.generateCartesianRhumbArc({
        positions: Cesium.Cartesian3.fromDegreesArray([70, 34, 130, 34]),
      }),
      width: 5,
      material: Cesium.Material.fromType("Color", {
        color: new Cesium.Color(0, 1, 0, 1),
      }),
    });
  }

  //渐隐线段
  fadingPolyline() {
    let polylines = this.scene.primitives.add(new Cesium.PolylineCollection());
    polylines.add({
      positions: Cesium.PolylinePipeline.generateCartesianArc({
        positions: Cesium.Cartesian3.fromDegreesArrayHeights([
          70, 35, 50000, 130, 35, 0,
        ]),
      }),
      width: 15,
      material: Cesium.Material.fromType(Cesium.Material.FadeType, {
        repeat: false, //控制线段是否重复
        fadeInColor: new Cesium.Color(1, 0, 0, 1),
        // fadeOutColor:new Cesium.Color(0,1,0,1),
        fadeOutColor: Cesium.Color.CYAN.withAlpha(0), //渐隐线段消失的颜色
        time: new Cesium.Cartesian2(0, 0),
        fadeDirection: { x: true, y: false }, // 控制渐隐方向
      }),
    });
  }

  //带箭头的线段
  localPolyline() {
    const localPolylines = this.scene.primitives.add(
      new Cesium.PolylineCollection()
    );
    const center = Cesium.Cartesian3.fromDegrees(119.0, 38);
    localPolylines.modelMatrix =
      Cesium.Transforms.eastNorthUpToFixedFrame(center);
    localPolylines.add({
      positions: [
        new Cesium.Cartesian3(0, 0, 0),
        new Cesium.Cartesian3(0, 1000000, 0),
      ],
      width: 10,
      material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType),
    });
  }
}

onMounted(async () => {
  viewer = new Cesium.Viewer(cesiumContainer.value, {
    baseLayerPicker: false, // 如果设置为false，将不会创建右上角图层按钮。
    fullscreenButton: false, // 如果设置为false，将不会创建右下角全屏按钮。
    vrButton: false, // 如果设置为false，将不会创建VR应用场景
    geocoder: false, // 如果设置为false，将不会创建右上角查询(放大镜)按钮。
    homeButton: false, // 如果设置为false，将不会创建右上角主页(房子)按钮。
    infoBox: false, // 是否显示点击要素之后显示的信息,cesium中的沙盒开关
    sceneModePicker: false, // 如果设置为false，将不会创建右上角投影方式控件(显示二三维切换按钮)。
    selectionIndicator: false, // 获取当选定实体更改时引发的事件。
    navigationHelpButton: false, // 如果设置为false，则不会创建右上角帮助(问号)按钮。
    navigationInstructionsInitiallyVisible: false, // 如果帮助说明最初应该是可见的，则为true；如果直到用户明确单击该按钮，则不显示该说明，否则为false。
    timeline: true, // 如果设置为false，则不会创建正下方时间轴小部件。
    scene3DOnly: true, // 为 true 时，每个几何实例将仅以3D渲染以节省GPU内存。
    animation: true, // 如果设置为false，将不会创建左下角动画小部件。
    shouldAnimate: false, // 默认true ，否则为 false 。此选项优先于设置 Viewer＃clockViewModel 。
    // ps. Viewer＃clockViewModel 是用于控制当前时间的时钟视图模型。我们这里用不到时钟，就把shouldAnimate设为false
    sceneMode: 3, // 初始场景模式 1 2D模式 2 2D循环模式 3 3D模式  Cesium.SceneMode
    requestRenderMode: false, // 启用请求渲染模式，不需要渲染，节约资源吧
    fullscreenElement: document.body, // 全屏时渲染的HTML元素 暂时没发现用处，虽然我关闭了全屏按钮，但是键盘按F11 浏览器也还是会进入全屏
    shadows: true,
  });

  //获取场景对象
  scene = viewer.scene;

  polylines=new Polylines(scene);

  scene.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(119, 40, 1000000),
    orientation: {
      heading: Cesium.Math.toRadians(0),
      pitch: Cesium.Math.toRadians(-90),
      roll: 0,
    },
  });
   polylines.widePolyline();
   polylines.basePloyline();
   polylines.coloredPolyline();
   polylines.loopPolyline();
   polylines.rhumbLine(); //恒向线 中间不需要输入更多的坐标来绘制就能变成曲线
   polylines.fadingPolyline(); //渐隐线段
   polylines.localPolyline(); //带箭头的线段

  const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
  handler.setInputAction((e) => {
    const pick = scene.pick(e.endPosition);
    if (
      Cesium.defined(pick) &&
      Cesium.defined(pick.node) &&
      Cesium.defined(pick.mesh)
    ) {
      console.log(`node:${pick.node.name},mesh:${pick.mesh.name}`);
    }
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
});
</script> 
<style scoped>
.cesiumContainer {
  width: 100%;
  height: 100vh;
}
</style>
